package com.skillworld.webapp.model.department.rank;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.skillworld.webapp.model.department.Department;
import com.skillworld.webapp.model.user.User;

@Entity
@Table(name="LevelDepartment")
public class DeptRank
{
	private Long deptRankId;
	private User user;
	private Department department;
	private int points;
	private int level;
	private Rank rank;
	private int grade;
/*	private Map<Locale,String> localizedRankName;*/
	private DeptRankDerived derived;


	protected DeptRank()
	{

	}

	public DeptRank(User user, Department department) 
	{
		this.user = user;
		this.department = department;
		this.points = 0;
		setLevel(0);
	}

	
	@SequenceGenerator(name="LevelDepartmentIdGenerator",sequenceName="LevelDepartmentSeq")
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO,generator="LevelDepartmentIdGenerator")
	@Column(name="idLevelDepartment")
	public Long getDeptRankId()
	{
		return deptRankId;
	}

	public void setDeptRankId(Long deptRankId)
	{
		this.deptRankId = deptRankId;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="idUser")
	public User getUser()
	{
		return user;
	}

	public void setUser(User user)
	{
		this.user = user;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="idDepartment")
	public Department getDepartment()
	{
		return department;
	}

	public void setDepartment(Department department)
	{
		this.department = department;
	}

	@Column(name = "points")
	public int getPoints()
	{
		return points;
	}

	protected void setPoints(int points)
	{
		this.points = points;
	}

    public void addPoints(int points)
    {
        this.points = points;
        updateLevel();
    }
	
	@Column(name = "level")
	public int getLevel() 
	{
		return level;
	}

    protected void setLevel(int level) 
    {
        rank = Rank.fromLevel(level);
        grade = level - rank.getBaseLevel();
        this.level = level;
    }
    
    @Transient
    public Rank getRank() 
    {
        return rank;
    }

    @Transient
    public int getGrade() 
    {
        return grade;
    }

    @Transient
    public boolean isMasterCoach()
    {
        return level >= Rank.MASTER_COACH.getBaseLevel();
    }

    @Transient
    public int getLevelPoints()
    {
        return rank.getBasePoints() +  grade*rank.getPointsPerGrade();
    }
    
    @Transient
    public int getUnusedPoints()
    {
        return points - getLevelPoints();
    }
    
    @Transient
    public int getPointsToPromoteLevel()
    {
        return rank.getPointsPerGrade() - getUnusedPoints();
    }
    
    protected void updateLevel()
    {
        int pointsLeft = points - getLevelPoints();
        
        while (pointsLeft >= rank.getPointsPerGrade())
        {
            pointsLeft -= rank.getPointsPerGrade();
            setLevel(level+1);
        }
    }

    @OneToOne(optional=true,fetch=FetchType.LAZY)
    @JoinColumn(name="idLevelDepartment")
    protected DeptRankDerived getDerived()
    {
        return derived;
    }

    protected void setDerived(DeptRankDerived derived) 
    {
        this.derived = derived;
    }
    
    @Transient
    public int getAcceptedTutorials()
    {
        if (derived != null) 
        { return derived.getAcceptedTutorials(); }
        else
        { return 0; }
    }
}
